#include "stdafx.h"

#ifndef DLL_EVENT_CPP
#define DLL_EVENT_CPP

#include "Event.h"

/*======================================================================*/
/*						 Event Manager */
/*======================================================================*/

/* ***********
 * PRIVATE *
 ************/


TEvent* _NULL_EVENT			=	new TEvent();
TEvent* _HEAD_EVENT			=	_NULL_EVENT;
TEvent* _TAIL_EVENT			=	_NULL_EVENT;

TEvent* _mCURRENTEVENT			=	_NULL_EVENT;

int _mEventStackCount			=	0;
int _mEventStackSize			=	128;
int _mEventEnableStack			=	0;


void _DeleteEvent (TEvent * ev)
{
	if (ev==_NULL_EVENT) return;
	
	if (ev==_mCURRENTEVENT) _mCURRENTEVENT=_NULL_EVENT;
	
	if (ev==_HEAD_EVENT)
	{
		if (ev==_TAIL_EVENT)
		{
			_HEAD_EVENT=_NULL_EVENT;
			_TAIL_EVENT=_NULL_EVENT;
			_mCURRENTEVENT=_NULL_EVENT;
		}
		else
		{
			_HEAD_EVENT=_HEAD_EVENT->_next;
			_HEAD_EVENT->_prev=_NULL_EVENT;
		};
	}
	else
	{
		if (ev==_TAIL_EVENT)
		{
			_TAIL_EVENT=_TAIL_EVENT->_prev;
			_TAIL_EVENT->_next=_NULL_EVENT;
		}
		else
		{
			ev->_next->_prev=ev->_prev;
			ev->_prev->_next=ev->_next;
		};
	};
	delete ev;
	_mEventStackCount--;
};

TEvent* FirstEvent(){return _HEAD_EVENT;};
TEvent* LastEvent(){return _TAIL_EVENT;};

/* ********
 * PUBLIC *
 **********/

BBAEXPvoid EmitEvent(int Event_Id,int Event_X,int Event_Y,char* Event_Data,int Event_Source)
{
	TEvent* e		=	new TEvent();
	e->_id			=	Event_Id;
	e->_x			=	Event_X;
	e->_y			=	Event_Y;
	e->_data		=	Event_Data;
	e->_src			=	Event_Source;
	
	if (_HEAD_EVENT==_NULL_EVENT)
	{
		_HEAD_EVENT=	e;
		e->_prev	=	_NULL_EVENT;
	}
	else
	{
		_TAIL_EVENT->_next=e;
		e->_prev	=	_TAIL_EVENT;
	};
	_TAIL_EVENT	=	e;
	e->_next		=	_NULL_EVENT;
	_mEventStackCount		++;
};

BBAEXPint PollEvent()
{
	// remove last interpreted event
	if (_mCURRENTEVENT!=_NULL_EVENT)
	{
		_DeleteEvent (_mCURRENTEVENT);
	};
	
	if (_HEAD_EVENT==_NULL_EVENT)	{_mEventStackCount=0;return 0;};

	if (_mEventEnableStack>0)
	{
		while(_mEventStackCount>_mEventStackSize)
		{
			if (_HEAD_EVENT==_NULL_EVENT)
			{
				_mEventStackCount=0;
				break;
			};
			_DeleteEvent (_HEAD_EVENT);
		};
	};
	
	if (_HEAD_EVENT==_NULL_EVENT)	{_mEventStackCount=0;return 0;};
	
	_mCURRENTEVENT=_HEAD_EVENT;
		
	return (_HEAD_EVENT!=_NULL_EVENT);
};


BBAEXPint EventID()
{
	if (_mCURRENTEVENT!=_NULL_EVENT) return _mCURRENTEVENT->_id;
	return 0;
};

BBAEXPint EventX()
{
	if (_mCURRENTEVENT!=_NULL_EVENT) return _mCURRENTEVENT->_x;
	return 0;
};

BBAEXPint EventY()
{
	if (_mCURRENTEVENT!=_NULL_EVENT) return _mCURRENTEVENT->_y;
	return 0;
};

BBAEXPint EventSource()
{
	if (_mCURRENTEVENT!=_NULL_EVENT) return _mCURRENTEVENT->_src;
	return 0;
};

BBAEXP char* BBACALL EventData()
{
	if (_mCURRENTEVENT!=_NULL_EVENT) return _mCURRENTEVENT->_data;
	return "";
};

BBAEXPvoid EventEnableStack(int enable)
{	_mEventEnableStack=(enable!=0);
};

BBAEXPint EventStackEnabled()
{	return (_mEventEnableStack!=0);
};

BBAEXPvoid SetEventStackSize(int Size)
{
	_mEventStackSize=Size;
};

BBAEXPint EventStackSize()
{
	return _mEventStackSize;
};

BBAEXPint CountEvents()
{
	return _mEventStackCount;
};


#endif //DLL_EVENT_CPP